﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using Business;
using Business.Entity.Estoque.Produto;
using Business.Entity.Vendas.MovimentacaoCaixa.SubClass.LancamentoInicial;
using Business.Entity.Vendas.Pedido.Restaurante;
using Business.Enum;
using DevExpress.LookAndFeel;
using DevExpress.XtraBars;
using DevExpress.XtraBars.Helpers;
using Ecf;
using Ecf.Forms;
using Remotion.Linq.Collections;
using Vendas.Controls;
using Vendas.Dialogs;
using Vendas.Forms;


namespace Vendas
{
    public partial class VendasRestaurante : DevExpress.XtraEditors.XtraForm
    {
        private static readonly string TempDir = Environment.CurrentDirectory + "\\temp";
        private readonly string _caminhoMesas = TempDir + "\\001.tmp";
        private readonly string _caminhoFilaSalao = TempDir + "\\002.tmp";
        private readonly string _caminhoFilaEntrega = TempDir + "\\003.tmp";
        public Control CurrentControl { get; set; }
        public ObservableCollection<PedidoRestaurante> FilaMesa { get; set; }
        public ObservableCollection<PedidoRestaurante> FilaEntrega { get; set; }


        public VendasRestaurante()
        {
            InitializeComponent();
            if (!EcfHelper.GetEcf().VerificaImpressora())
            {
                Process.GetCurrentProcess().Kill();
            }

            VerificaPermissaoInicial();
            contentPanel.Controls.Remove(tileControl1);
            contentPanel.Controls.Remove(filaEntregaGridControl);
            contentPanel.Controls.Remove(filaMesaGridControl);
            comandosPedido.Visible = false;
            comandosFilaPageGroup.Visible = false;
            SkinHelper.InitSkinGallery(temasRibbonGallery, true);
            UserLookAndFeel.Default.StyleChanged += Default_StyleChanged;
            if (DateTime.Now.Date > Utils.Configuracao.DiaProcessamento.Date)
            {

            }
            if (LancamentoInicialRepository.DiaLancado(Utils.Terminal.ConfiguracaoEcf.Caixa) != null)
            {
                new FormLancamentoInicial().ShowDialog();
            }

            CarregarBackup();
            txtUsuario.EditValue = Utils.UsuarioAtual.Pessoa.Nome;
            grpExibir.Visible = false;
            var l = LancamentoInicialRepository.DiaLancado(Utils.Terminal.ConfiguracaoEcf.Caixa);
            if (l == null)
            {
                new FormLancamentoInicial().ShowDialog();
            }
        }



        void MenuFiscal_MesasAbertas(object sender, EventArgs e)
        {
            ExibirMesasAbertas();
        }

        void MenuFiscal_TransferirMesa(object sender, EventArgs e)
        {
            TrocarMesa();
        }

        private void VerificaPermissaoInicial()
        {
            if (!Utils.Terminal.RestauranteAtivo)
            {
                MessageBox.Show("Este terminal não está habilitado para funcionar com" +
                                " o módulo de restaurante.");
                Process.GetCurrentProcess().Kill();
            }
            if (Utils.Terminal.ConfiguracaoEcf == null)
            {
                MessageBox.Show("O ECF não foi configurado para este terminal.");
                Process.GetCurrentProcess().Kill();
            }
            if (!Utils.UsuarioAtual.UsaVendaRestaurante)
            {
                MessageBox.Show("Este usuário não tem permissão para acessar este módulo do sistema.");
                Process.GetCurrentProcess().Kill();
            }
        }

        void Default_StyleChanged(object sender, System.EventArgs e)
        {
            Properties.Settings.Default.SkinName = UserLookAndFeel.Default.SkinName;
            Properties.Settings.Default.Save();
        }

        private void Inicial_Load(object sender, System.EventArgs e)
        {



        }


        private void cmdAdicionarMesa_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            AbrirMesa();
        }

        private void AbrirMesa()
        {
            
            var p = new PedidoControl();
            AddPedidoEvents(p);
            p.AbrirPedido(LocalPedidoRestaurante.Mesa);
            if (p.Pedido.Mesa == 0)
            {
                return;
            }
            ExibirControle(p);
        }

        private void AddPedidoEvents(PedidoControl p)
        {
            p.OnPedidoAberto += FormPedidoAberto;
            p.OnPedidoCancelado += FormPedidoCancelado;
            p.OnPedidoConfirmado += FormPedidoConfirmado;
            p.OnPedidoFechado += FormPedidoFechado;
            p.OnLocalPedidoAlterado += FormLocalPedidoAlterado;
            p.OnProdutoAdicionado += p_OnProdutoAdicionado;
            p.KeyDown += Inicial_KeyDown;
        }

        void p_OnProdutoAdicionado(object sender, PedidoEventArgs e)
        {
            BackupTela();
        }

        private void FormLocalPedidoAlterado(object sender, LocalPedidoAlteradoEventArgs localPedidoAlteradoEventArgs)
        {

        }

        private void FormPedidoFechado(object sender, PedidoEventArgs e)
        {
            if (e.Pedido.Pedido.Confirmado)
            {
                if (e.Pedido.TileControl != null)
                {
                    mesaGroup.Items.Remove(e.Pedido.TileControl);
                    e.Pedido.TileControl.Dispose();
                    IList<object> remover = new List<object>();
                    foreach (PedidoControl mesa in filaMesaBindingSource)
                    {
                        if (mesa.Pedido.Mesa == e.Pedido.Pedido.Mesa)
                        {
                            remover.Add(mesa);
                        }
                    }
                    foreach (var o in remover)
                    {
                        filaMesaBindingSource.Remove(o);
                    }
                }
                else
                {
                    filaEntregaBindingSource.Remove(e.Pedido);
                    var ret = MessageBox.Show("O pedido não foi impresso ainda deseja" +
                                              " imprimir uma via para a cozinha?", "Atenção", MessageBoxButtons.YesNo);
                    if (ret == DialogResult.Yes)
                    {
                        RestauranteUtils.ImprimirPedido(e.Pedido.Pedido);
                    }
                }
            }
            else
            {
                e.Pedido.Pedido.Confirmado = true;
                if (e.Pedido.Pedido.Local == LocalPedidoRestaurante.Entrega)
                {

                    filaEntregaBindingSource.Add(e.Pedido);
                }
                else
                {
                    filaMesaBindingSource.Add(e.Pedido);
                }
            }
            BackupTela();
            LimparTela();
        }

        private void FormPedidoConfirmado(object sender, PedidoEventArgs e)
        {


            if (e.Pedido.Pedido.Local == LocalPedidoRestaurante.Mesa)
            {
                // Verifica se há uma mesa já aberta para poder inserir os produtos.
                foreach (MesaTileControl item in mesaGroup.Items)
                {
                    // Verifica se a mesa aberta é a mesma que está sendo confirmada.
                    if (item.Pedido.Pedido.Mesa == e.Pedido.Pedido.Mesa)
                    {
                        // Se o número da mesa for o mesmo que está sendo confirmada adiciona os produtos.
                        foreach (var prod in e.Pedido.Pedido.Produtos)
                        {
                            item.Pedido.AddProduto(prod);
                        }
                    }
                }
                // Adiciona o pedido à fila do salão.
                filaMesaBindingSource.Add(e.Pedido);
            }
            else
            {
                // Verifica se é um pedido para balcão.
                if (e.Pedido.Pedido.Local == LocalPedidoRestaurante.Balcao)
                {
                    // Adiciona à fila do salão.
                    filaMesaBindingSource.Add(e.Pedido);
                }
                else // Trata do pedido para entrega.
                {
                    // Adiciona à fila para entrega.
                    filaEntregaBindingSource.Add(e.Pedido);
                }
            }
            #region Verifica a necessidade de se criar um novo MesaTileControl para manter a mesa.
            // Verifica se é um pedido de mesa para verificar se já existe uma mesa aberta.
            if (e.Pedido.Pedido.Local == LocalPedidoRestaurante.Mesa)
            {
                bool existeMesaAberta = false;
                // Verifica na lista se existe uma mesa aberta.
                foreach (MesaTileControl item in mesaGroup.Items)
                {
                    if (item.Pedido.Pedido.Mesa == e.Pedido.Pedido.Mesa)
                    {
                        existeMesaAberta = true;
                    }
                }
                // Se não existir uma mesa aberta cria um MesaTileControl para poder manter a mesa aberta.
                if (!existeMesaAberta)
                {
                    var m = new MesaTileControl(e.Pedido);
                    m.OnExibirMesa += FormExibirMesa;
                    mesaGroup.Items.Add(m);
                }
            }
            #endregion
            if (e.Pedido.Pedido.Local == LocalPedidoRestaurante.Mesa)
            {
                ExibirControle(tileControl1);
            }
            else LimparTela();
            e.Pedido.Pedido.Confirmado = true;
            BackupTela();
        }

        private void FormPedidoCancelado(object sender, PedidoEventArgs e)
        {
            // Verifica se há uma mesa aberta para poder excluí-la.
            if (e.Pedido.TileControl != null)
            {
                IList<Object> remover = new List<object>();

                // Remove os pedidos que existem na fila correspondentes à mesa.
                foreach (var item in filaMesaBindingSource)
                {
                    var pedido = (PedidoControl)item;
                    if (pedido.Pedido.Mesa == e.Pedido.Pedido.Mesa)
                    {
                        remover.Add(pedido);
                    }
                }
                foreach (var item in remover)
                {
                    filaMesaBindingSource.Remove(item);
                }
                // Elimina o MesaTileControl
                mesaGroup.Items.Remove(e.Pedido.TileControl);
                e.Pedido.TileControl.Dispose();
            }
            else
            {
                filaEntregaBindingSource.Remove(e.Pedido.TelaPedidoControl);
            }
            BackupTela();
            LimparTela();
        }

        void FormPedidoAberto(object sender, PedidoEventArgs e)
        {


        }

        void FormExibirMesa(object sender, ExibirPedidoEventArgs e)
        {
            ExibirControle(e.PedidoControl);
        }

        private void ExibirControle(Control control)
        {
            if (CurrentControl != null)
            {

                contentPanel.Controls.Remove(CurrentControl);
                CurrentControl = null;
            }

            CurrentControl = control;
            CurrentControl.Focus();
            CurrentControl.Anchor = contentPanel.Anchor; CurrentControl.Size = contentPanel.Size;
            CurrentControl.Location = new Point(0, 0);
            contentPanel.Controls.Add(CurrentControl);
            CurrentControl.Focus();
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                var p = (PedidoControl)CurrentControl;
                p.ConfigurarFoco();
                comandosPedido.Visible = true;
                cmdConfirmarPedido.Enabled = !p.Confirmado;
                if (p.Pedido.Local == LocalPedidoRestaurante.Balcao ||
                    p.Pedido.Local== LocalPedidoRestaurante.Entrega)
                {
                    cmdFecharPedido.Enabled = false;
                }
                else
                {
                    cmdFecharPedido.Enabled = true;
                }
            }
            else comandosPedido.Visible = false;
            if (CurrentControl.Name.Equals(tileControl1.Name) ||
                CurrentControl.Name.Equals(filaEntregaGridControl.Name) ||
                CurrentControl.Name.Equals(filaMesaGridControl.Name))
            {
                grpExibir.Visible = true;
            }
            else
            {
                grpExibir.Visible = false;
            }
            if (CurrentControl.Name.Equals(filaEntregaGridControl.Name) ||
                CurrentControl.Name.Equals(filaMesaGridControl.Name))
            {
                comandosFilaPageGroup.Visible = true;
                grpExibir.Visible = true;
            }
            else
            {
                comandosFilaPageGroup.Visible = false;
            }
        }
        private void cmdAddPedidoBalcao_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            var p = new PedidoControl();
            AddPedidoEvents(p);
            p.AbrirPedido(LocalPedidoRestaurante.Balcao);
            ExibirControle(p);
        }

        private void cmdMesasAbertas_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ExibirMesasAbertas();
        }

        private void ExibirMesasAbertas()
        {
            ExibirControle(tileControl1);

        }

        private void cmdMostrarFilaMesas_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

            ExibirControle(filaMesaGridControl);

        }

        private void cmdMostrarFilaEntrega_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ExibirControle(filaEntregaGridControl);
        }

        private void barButtonItem8_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            var p = new PedidoControl();
            AddPedidoEvents(p);
            p.AbrirPedido(LocalPedidoRestaurante.Entrega);
            ExibirControle(p);
        }

        private void cmdLimparTela_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            LimparTela();
        }

        private void LimparTela()
        {
            if (CurrentControl != null)
            {
                contentPanel.Controls.Remove(CurrentControl);
                comandosFilaPageGroup.Visible = false;
                comandosPedido.Visible = false;
                CurrentControl = null;
                grpExibir.Visible = false;
            }
        }

        private void Inicial_KeyDown(object sender, KeyEventArgs e)
        {
            if (CurrentControl != null)
            {
                if (CurrentControl.GetType() == typeof(PedidoControl))
                {
                    var p = (PedidoControl)CurrentControl;

                }
            }

        }

        private void barButtonItem5_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                ((PedidoControl)CurrentControl).ConfirmarPedido();
            }
        }

        private void cmdFecharPedido_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                var pedido = (PedidoControl)CurrentControl;
                if (pedido.Pedido.Local == LocalPedidoRestaurante.Mesa)
                {
                    FecharMesa();
                }
                else
                {
                    pedido.FecharPedido();
                }
            }
        }

        private void FecharMesa()
        {
            // Pega o controle que está sendo exibido atualmente.

            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                var currentPedido = (PedidoControl)CurrentControl;
                if (!currentPedido.Confirmado)
                {
                    currentPedido.ConfirmarPedido();
                    currentPedido.TileControl.ExibirMesa();
                    currentPedido.FecharPedido();
                    LimparTela();
                }
                else
                {
                    IPedidoRestauranteItem item = null;
                    foreach (MesaTileControl mesa in mesaGroup.Items)
                    {
                        if (mesa.Pedido.Pedido.Mesa == currentPedido.Pedido.Mesa)
                        {
                            if (currentPedido.Pedido.Produtos.Count > 0 && !currentPedido.Pedido.Confirmado)
                            {
                                var result = MessageBox.Show("Deseja incluir os itens na mesa?", "Atenção",
                                    MessageBoxButtons.YesNo);
                                if (result == DialogResult.Yes)
                                {
                                    foreach (var prod in currentPedido.Pedido.Produtos)
                                    {
                                        mesa.Pedido.TelaPedidoControl.AddProduto(prod);
                                    }
                                }
                            }
                            ExibirControle(mesa.Pedido.TelaPedidoControl);
                            mesa.ExibirMesa();
                            item = mesa.Pedido;
                        }
                    }
                    if (item != null) item.FecharPedido();
                }


            }

        }

        private void cmdCancelarPedido_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                ((PedidoControl)CurrentControl).CancelarPedido();
            }
        }

        private void cmdProdDescricao_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                ((PedidoControl)CurrentControl).PesquisarDescricao();
            }
        }

        private void cmdProdCodBarra_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                ((PedidoControl)CurrentControl).PesquisarCodBarra();
            }
        }

        private void cmdProdReferencia_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                ((PedidoControl)CurrentControl).PesquisarReferencia();
            }
        }

        private void cmdAlterarCliente_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                ((PedidoControl)CurrentControl).AlterarCliente();
            }
        }

        private void cmdSuprimento_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            new FormSuprimento().ShowDialog();
        }

        private void cmdSangria_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            new FormSangria().ShowDialog();
        }

        private void cmdPagamentoCliente_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            new FormPagamentoCliente().ShowDialog();
        }

        private void cmdFechamento_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            new FormFechamento().ShowDialog();
        }

        private void temasRibbonGallery_GalleryItemClick(object sender, DevExpress.XtraBars.Ribbon.GalleryItemClickEventArgs e)
        {

        }

        private void cmdBuscaItemFila_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {

            if (CurrentControl == null)
            {
                return;
            }
            using (var fMesa = new FormNumeroMesa("Controle"))
            {
                var numero = fMesa.GetMesa();
                if (fMesa.DialogResult == DialogResult.Cancel)
                {
                    return;
                }
                if (CurrentControl.Name.Equals(filaMesaGridControl.Name))
                {
                    filaMesaBindingSource.MoveFirst();
                    foreach (PedidoControl mesa in filaMesaBindingSource)
                    {
                        if (mesa.Pedido.Controle.Controle == numero)
                        {
                            return;
                        }
                        filaMesaBindingSource.MoveNext();
                    }
                }
                if (CurrentControl.Name.Equals(filaEntregaGridControl.Name))
                {


                    filaEntregaBindingSource.MoveFirst();
                    foreach (PedidoControl mesa in filaMesaBindingSource)
                    {
                        if (mesa.Pedido.Controle.Controle == numero)
                        {
                            return;
                        }
                        filaEntregaBindingSource.MoveNext();
                    }
                }
            }

        }

        private void cmdAlterarComposicao_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                var ctrl = (PedidoControl)CurrentControl;
                ctrl.EditarComposicao();
            }
        }

        private void cmdMostrarMesa_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.Name.Equals(filaEntregaGridControl.Name) ||
                CurrentControl.Name.Equals(filaMesaGridControl.Name))
            {
                var ctrlAtual = CurrentControl;
                if (ctrlAtual == null)
                {
                    return;
                }
                if (ctrlAtual.Name == filaEntregaGridControl.Name)
                {
                    var atual = (IPedidoRestauranteItem)filaEntregaBindingSource.Current;
                    if (atual == null)
                    {
                        return;
                    }
                    ExibirControle(new PedidoControl(atual.Pedido));
                }
                if (ctrlAtual.Name == filaMesaGridControl.Name)
                {
                    var atual = (IPedidoRestauranteItem)filaMesaBindingSource.Current;
                    if (atual == null)
                    {
                        return;
                    }
                    ExibirControle(new PedidoControl(atual.Pedido));
                }
            }
            else
            {
                var intMesa = new FormNumeroMesa().GetMesa();
                if (intMesa == 0)
                {
                    return;
                }
                foreach (var item in mesaGroup.Items)
                {
                    if (item.GetType() == typeof(MesaTileControl))
                    {
                        var mesa = (MesaTileControl)item;
                        if (mesa.Pedido.Pedido.Mesa == intMesa)
                        {
                            mesa.ExibirMesa();
                        }
                    }
                }
            }
        }


        private void cmdFecharPedidoFila_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.Name == filaMesaGridControl.Name)
            {
                var item = (IPedidoRestauranteItem)filaMesaBindingSource.Current;
                if (item.Pedido.Local == LocalPedidoRestaurante.Balcao)
                {
                    ExibirControle(new PedidoControl(item.Pedido));
                    item.FecharPedido();
                }
                if (item.Pedido.Local == LocalPedidoRestaurante.Mesa)
                {
                    MessageBox.Show("Para fechar uma mesa acesse a lista de mesas ou" +
                                    " acesse a mesa desejada pela opção 'Exibir mesa'");
                    return;
                }
            }
            if (CurrentControl.Name == filaEntregaGridControl.Name)
            {
                var item = (IPedidoRestauranteItem)filaEntregaBindingSource.Current;
                ExibirControle(new PedidoControl(item.Pedido));
                item.FecharPedido();
            }
        }

        private void cmdParcialMesa_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            var mesa = new FormNumeroMesa().GetMesa();
            if (CurrentControl != null)
                if (CurrentControl.GetType() == typeof(PedidoControl))
                {

                    var pedido = (PedidoControl)CurrentControl;
                    pedido.FinalizarEdicao();
                    if (!pedido.Pedido.Confirmado && pedido.Pedido.Local == LocalPedidoRestaurante.Mesa)
                    {
                        pedido.ConfirmarPedido();
                    }
                }
            foreach (var tileMesa in mesaGroup.Items)
            {
                if (tileMesa.GetType() == typeof(MesaTileControl))
                {
                    var m = (MesaTileControl)tileMesa;
                    if (m.Pedido.Pedido.Mesa == mesa)
                    {
                        m.Pedido.ParcialMesa(); return;
                    }
                }
            }
            MessageBox.Show("Mesa não encontrada.");
        }

        private void BackupTela()
        {

            if (!Directory.Exists(TempDir))
            {
                Directory.CreateDirectory(TempDir);
            }


            if (File.Exists(_caminhoMesas))
            {
                File.Delete(_caminhoMesas);
            }
            if (File.Exists(_caminhoFilaSalao))
            {
                File.Delete(_caminhoFilaSalao);
            }
            if (File.Exists(_caminhoFilaEntrega))
            {
                File.Delete(_caminhoFilaEntrega);
            }

            // Arquivo das mesas do sistema.
            var fMesas = new FileStream(_caminhoMesas, FileMode.OpenOrCreate);
            // Arquivo com a fila do salão.
            var fFilaSalao = new FileStream(_caminhoFilaSalao, FileMode.OpenOrCreate);
            // Arquivo com a fila de entrega.
            var fFilaFilaEntrega = new FileStream(_caminhoFilaEntrega, FileMode.OpenOrCreate);

            var bf = new BinaryFormatter();

            bf.Serialize(fMesas, GetMesasAbertas());
            bf.Serialize(fFilaSalao, GetFilaSalao());
            bf.Serialize(fFilaFilaEntrega, GetFilaEntrega());

            fMesas.Close();
            fFilaFilaEntrega.Close();
            fFilaSalao.Close();
        }
        private void CarregarBackup()
        {
            var bf = new BinaryFormatter();
            if (File.Exists(_caminhoMesas))
            {
                try
                {
                    var stream = new FileStream(_caminhoMesas, FileMode.Open);
                    var mesas = (List<PedidoRestaurante>)bf.Deserialize(stream);
                    mesaGroup.Items.Clear();
                    foreach (var pedido in mesas)
                    {
                        var ctrl = new Vendas.Forms.PedidoControl(pedido);
                        foreach (var comp in pedido.Produtos)
                        {
                            comp.Produto = ProdutoRepository.GetById(comp.Produto.Id);
                            foreach (var prod in comp.Composicao)
                            {
                                prod.Produto = ProdutoRepository.GetById(prod.Id);
                            }
                        }
                        ctrl.Pedido = pedido;
                        AddPedidoEvents(ctrl);
                        var m = new MesaTileControl(ctrl);
                        m.OnExibirMesa += FormExibirMesa;
                        mesaGroup.Items.Add(m);
                    }
                    stream.Close();
                }
                catch (Exception)
                {
                    MessageBox.Show("Erro ao carregar mesas abertas.");
                }

            }
            if (File.Exists(_caminhoFilaSalao))
            {
                try
                {
                    var stream = new FileStream(_caminhoFilaSalao, FileMode.Open);
                    var fila = (List<PedidoRestaurante>)bf.Deserialize(stream);

                    //filaMesaBindingSource.DataSource = fila;
                    filaMesaBindingSource.Clear();
                    foreach (var pedido in fila)
                    {
                        foreach (var comp in pedido.Produtos)
                        {
                            comp.Produto = ProdutoRepository.GetById(comp.Produto.Id);
                            foreach (var prod in comp.Composicao)
                            {
                                prod.Produto = ProdutoRepository.GetById(prod.Id);
                            }
                        }
                        var ctrl = new PedidoControl(pedido) { Pedido = pedido };
                        AddPedidoEvents(ctrl);
                        filaMesaBindingSource.Add(ctrl);
                    }
                    filaEntregaBindingSource.EndEdit();
                    stream.Close();
                }
                catch (Exception)
                {
                    MessageBox.Show("Erro ao carregar fila do salão.");
                }

            }
            if (File.Exists(_caminhoFilaEntrega))
            {
                try
                {
                    var stream = new FileStream(_caminhoFilaEntrega, FileMode.Open);
                    var fila = (List<PedidoRestaurante>)bf.Deserialize(stream);
                    //filaEntregaBindingSource.DataSource = fila;
                    filaEntregaBindingSource.Clear();
                    foreach (var pedido in fila)
                    {
                        var ctrl = new PedidoControl(pedido);
                        ctrl.Pedido = pedido;
                        AddPedidoEvents(ctrl);
                        filaEntregaBindingSource.Add(ctrl);
                    }
                    stream.Close();
                }
                catch (Exception)
                {
                    MessageBox.Show("Erro ao carregar fila de entrega.");
                }

            }
        }
        private object GetMesasAbertas()
        {
            var lista = new List<PedidoRestaurante>();
            foreach (MesaTileControl mesa in mesaGroup.Items)
            {
                lista.Add(mesa.Pedido.Pedido);
            }
            return lista;
        }

        private object GetFilaSalao()
        {
            var lista = new List<PedidoRestaurante>();
            foreach (PedidoControl pedido in filaMesaBindingSource)
            {
                lista.Add(pedido.Pedido);
            }
            return lista;
        }

        private object GetFilaEntrega()
        {
            var lista = new List<PedidoRestaurante>();
            foreach (PedidoControl pedido in filaEntregaBindingSource)
            {
                lista.Add(pedido.Pedido);
            }
            return lista;
        }

        private void cmdTrocarMesa_ItemClick(object sender, ItemClickEventArgs e)
        {
            TrocarMesa();
        }

        private void TrocarMesa()
        {
            LimparTela();
            var origem = new FormNumeroMesa().GetMesa("Mesa de origem");
            if (origem == 0)
            {
                return;
            }
            var destino = new FormNumeroMesa().GetMesa("Mesa de destino");
            if (destino == 0)
            {
                return;
            }
            var mOrigem = GetMesa(origem);
            var mDestino = GetMesa(destino);
            if (mOrigem == null)
            {
                MessageBox.Show("A mesa de origem não está aberta no momento.");
                return;
            }

            if (mDestino == null)
            {
                var tile = GetMesaTileControl(origem);
                if (tile != null)
                {
                    tile.TrocarMesa(destino);
                }
            }
            else
            {
                if (mOrigem.Pedido.Mesa == mDestino.Pedido.Mesa)
                {
                    MessageBox.Show("Não é possível transferir para a mesma mesa.");
                    return;
                }
                else
                {
                    var result = MessageBox.Show("Já existe uma mesa em aberto com esse número.\n" +
                                                 "Deseja juntar o consumo na mesa de destino?", "Atenção", MessageBoxButtons.YesNo);
                    if (result == DialogResult.Yes)
                    {
                        var tile = GetMesaTileControl(origem);
                        foreach (var prod in tile.Pedido.Pedido.Produtos)
                        {
                            mDestino.AddProduto(prod);
                        }
                        mesaGroup.Items.Remove(tile);
                        tile.Dispose();

                    }
                }
            }


            BackupTela();

        }

        private MesaTileControl GetMesaTileControl(int mesa)
        {
            foreach (MesaTileControl m in mesaGroup.Items)
            {
                if (m.Pedido.Pedido.Mesa == mesa)
                {
                    return m;
                }
            }
            return null;
        }

        private PedidoControl GetMesa(int mesa)
        {
            foreach (MesaTileControl m in mesaGroup.Items)
            {
                if (m.Pedido.Pedido.Mesa == mesa)
                {
                    return m.Pedido.TelaPedidoControl;
                }
            }
            return null;
        }

        private void cmdCancelarPedidoFila_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.Name == filaMesaGridControl.Name)
            {
                filaMesaBindingSource.Remove(filaMesaBindingSource.Current);
            }
            if (CurrentControl.Name == filaEntregaGridControl.Name)
            {
                filaEntregaBindingSource.Remove(filaMesaBindingSource.Current);
            }
        }

        private void cmdObservacaoPedido_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl == null)
            {
                return;
            }
            if (CurrentControl.GetType() == typeof(PedidoControl))
            {
                var p = (PedidoControl)CurrentControl;
                p.MostrarObservacoes();
            }
        }

        private void cmdMenuFiscal_ItemClick(object sender, ItemClickEventArgs e)
        {
            var menu = new FormMenuFiscal(FormMenuFiscal.MenuFiscalTipo.Restaurante);
            menu.TransferirMesa += MenuFiscal_TransferirMesa;
            menu.MesasAbertas += MenuFiscal_MesasAbertas;
            menu.ShowDialog();
        }

        private void tmrHora_Tick(object sender, EventArgs e)
        {
            txtHora.EditValue = DateTime.Now;
        }

    }

}